package com.ldf.jrtsp.parser;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * rtp数据解析
 *
 * @author lidaofu
 * @since 2024/6/21
 **/
public class RtpDataParser {
    private int version;
    private int padding;
    private int extension;
    private int csrcCount;
    private int marker;
    private int payloadType;
    private int sequenceNumber;
    private long timestamp;
    private int ssrc;
    private int profile;
    private byte[] rawData;


    public RtpDataParser(byte[] data, int offset, int size) {
        parse(data, offset, size);
    }

    public RtpDataParser(byte[] data) {
        parse(data, 0, data.length);
    }

    private void parse(byte[] data, int offset, int size) {
        version = (data[offset] & 0xC0) >> 6;
        padding = (data[offset] & 0x20) >> 5;
        extension = (data[offset] & 0x10) >> 4;
        csrcCount = data[offset] & 0x0F;
        marker = (data[++offset] & 0x80) >> 7;
        payloadType = data[offset] & 0x7F;
        sequenceNumber = ((data[++offset] & 0xFF) << 8) | (data[++offset] & 0xFF);
        timestamp = ((long)(data[++offset] & 0xFF) << 24) | ((long)(data[++offset] & 0xFF) << 16) | ((long)(data[++offset] & 0xFF) << 8) | ((long)data[++offset] & 0xFF);
        ssrc = ((data[++offset] & 0xFF) << 24) | ((data[++offset] & 0xFF) << 16) | ((data[++offset] & 0xFF) << 8) | (data[++offset] & 0xFF);
        if (csrcCount > 0) {
            offset += csrcCount * 4;
        }
        if (extension == 1) {
            profile = ((data[++offset] & 0xFF) << 8) | (data[++offset] & 0xFF);
            int length = ((data[++offset] & 0xFF) << 8) | (data[++offset] & 0xFF);
            offset += length * 4;
        }
        offset ++;
        int paddingCount = 0;
        if (padding == 1) {
            paddingCount = data[size - 1] & 0xFF;
        }
        int rawDataSize = size - offset - paddingCount;
        if (rawDataSize != 0) {
            rawData = new byte[rawDataSize];
            System.arraycopy(data, offset, rawData, 0, rawDataSize);
        }
        //log.info("version:{},padding:{},extension:{},csrcCount:{},marker:{},payloadType:{},sequenceNumber:{},timestamp:{},ssrc:{},size:{}", version, padding, extension, csrcCount, marker, payloadType, sequenceNumber, timestamp, ssrc, rawData.length);
    }


    public int getVersion() {
        return version;
    }

    public void setVersion(int version) {
        this.version = version;
    }

    public int getPadding() {
        return padding;
    }

    public void setPadding(int padding) {
        this.padding = padding;
    }

    public int getExtension() {
        return extension;
    }

    public void setExtension(int extension) {
        this.extension = extension;
    }

    public int getCsrcCount() {
        return csrcCount;
    }

    public void setCsrcCount(int csrcCount) {
        this.csrcCount = csrcCount;
    }

    public int getMarker() {
        return marker;
    }

    public void setMarker(int marker) {
        this.marker = marker;
    }

    public int getPayloadType() {
        return payloadType;
    }

    public void setPayloadType(int payloadType) {
        this.payloadType = payloadType;
    }

    public int getSequenceNumber() {
        return sequenceNumber;
    }

    public void setSequenceNumber(int sequenceNumber) {
        this.sequenceNumber = sequenceNumber;
    }

    public long getTimestamp() {
        return timestamp;
    }

    public void setTimestamp(long timestamp) {
        this.timestamp = timestamp;
    }

    public int getSsrc() {
        return ssrc;
    }

    public void setSsrc(int ssrc) {
        this.ssrc = ssrc;
    }

    public int getProfile() {
        return profile;
    }

    public void setProfile(int profile) {
        this.profile = profile;
    }

    public byte[] getRawData() {
        return rawData;
    }

    public void setRawData(byte[] rawData) {
        this.rawData = rawData;
    }
}
